import configPromise from '@payload-config';
import { notFound } from 'next/navigation';
import type { Metadata } from 'next/types';
import { getPayload } from 'payload';
import React, { cache } from 'react';

import { PostsList } from '@/components/PostsList';

export const revalidate = 600;

type Args = {
  params: Promise<{
    slug: string;
    pageNumber: string;
  }>;
};

export default async function Page({ params: paramsPromise }: Args) {
  const { slug, pageNumber } = await paramsPromise;

  const sanitizedPageNumber = Number(pageNumber);

  if (!Number.isInteger(sanitizedPageNumber)) notFound();

  const category = await queryCategoryBySlug({ slug });

  if (!category) {
    notFound();
  }

  return (
    <div className='pb-12'>
      <div className='container mb-16'>
        <div className='prose max-w-none dark:prose-invert'>
          <h1>{category.title}</h1>
        </div>
      </div>

      <PostsList postType='hub' categorySlug={slug} page={sanitizedPageNumber} />
    </div>
  );
}

export async function generateMetadata({ params: paramsPromise }: Args): Promise<Metadata> {
  const { slug, pageNumber } = await paramsPromise;
  const category = await queryCategoryBySlug({ slug });

  return {
    title: `${category?.title || 'Category'} - Page ${pageNumber} | Hub`,
  };
}

export async function generateStaticParams() {
  const payload = await getPayload({ config: configPromise });
  const categories = await payload.find({
    collection: 'categories',
    limit: 1000,
    overrideAccess: true,
  });

  const params: { slug: string; pageNumber: string }[] = [];

  // For each category, calculate how many pages of hub posts exist
  for (const category of categories.docs) {
    const where = {
      categories: {
        contains: category.id,
      },
      postType: {
        equals: 'hub',
      },
    };

    const hubCount = await payload.count({
      collection: 'posts',
      where,
      overrideAccess: false,
    });

    const totalPages = Math.ceil(hubCount.totalDocs / 15); // Using 15 items per page for hub

    for (let i = 1; i <= totalPages; i++) {
      params.push({
        slug: category.slug!,
        pageNumber: String(i),
      });
    }
  }

  return params;
}

const queryCategoryBySlug = cache(async ({ slug }: { slug: string }) => {
  const payload = await getPayload({ config: configPromise });

  const categories = await payload.find({
    collection: 'categories',
    where: {
      slug: {
        equals: slug,
      },
    },
    limit: 1,
  });

  return categories.docs[0] || null;
});
